struct Edge {
	int from, to, wei;
};

inline bool cmpEdge(const Edge& a, const Edge& b) {
	return a.from < b.from;
}

Edge edges[maxm];
int startPos[maxn], dis[maxn];

void BFS(int u0) {
	int que[maxn], qhead = 0, qtail = 1;
	vis[que[qhead] = u0] = true;
	dis[u0] = 0;
	while (qhead < qtail) {
		int u = que[qhead ++];
		for (int e = startPos[u]; e < startPos[u + 1]; ++ e) {
			if (!vis[edges[e].to]) {
				vis[edges[e].to] = true;
				dis[edges[e].to] = dis[u] + 1;
				que[qtail ++] = edges[e].to;
			}
		}
	}
}

int main() {
	cin >> n >> m;
	for (int i = 0; i < m; ++ i) {
		cin >> edges[i].from >> edges[i].to >> edges[i].wei;
	}
	std::sort(edges, edges + m, cmpEdge);
	for (int u = 1, e = 0; u <= n; ++ u) {
		startPos[u] = e;
		while (e < m && edges[e].from == u) ++ e;
	}
	startPos[n + 1] = m;
	for (int i= 1; i <= n; ++ i) {
		if (!vis[i]) {
			BFS(i);
		}
	}
}
